package com.titaniume.exer;

import java.util.concurrent.locks.ReentrantLock;

/**
 *@program: JavaSenior
 *@description:
 * 银行有一个账户。
 * 有两个储户分别向同一个账户存3000元，每次存1000，存3次。每次存完打
 * 印账户余额。
 * 问题：该程序是否有安全问题，如果有，如何解决？
 *
 *
 * 分析：
 * 1.是否是多线程问题？ 是  ，两个储户线程
 * 2.是否有共享数据？ 有 账户或（账户余额）
 * 3.是否有线程安全问题？ 有
 * 4.需要考虑如何解决线程安全问题
 *
 *@author: renfei.huang
 *@create: 2021-09-30 09:36
 */
public class AccountTest {

    public static void main(String[] args) {

        Account account = new Account(0);

        Customer c1 = new Customer(account);
        Customer c2 = new Customer(account);

        c1.setName("甲");
        c2.setName("乙 ");
        c1.start();
        c2.start();
    }
}


class Account{

    private double balance;

    public Account(double balance) {
        this.balance = balance;
    }

    private static ReentrantLock reentrantLock = new ReentrantLock();

    //存钱 synchronized 方式
//    public synchronized void  deposit(double amt){
//        if(amt > 0){
//            balance += amt;
//
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//
//            System.out.println(Thread.currentThread().getName()+":"+"存钱成功,余额为："+balance);
//        }
//    }


    //ReentrantLock 方式
    public  void  deposit(double amt){
        try{
            reentrantLock.lock();
            if(amt > 0){
                balance += amt;

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName()+":"+"存钱成功,余额为："+balance);
            }
        }finally {
            reentrantLock.unlock();
        }

    }
}

class Customer extends  Thread{

    private Account account;

    public Customer(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3 ; i++) {
            account.deposit(1000);
        }
    }
}
